home *** CD-ROM | disk | FTP | other *** search
- /*
- SNEWS 2.0
-
- snews - a simple threaded news reader
-
-
- Copyright (C) 1991 John McCombs, Christchurch, NEW ZEALAND
- john@ahuriri.gen.nz
- PO Box 2708, Christchurch, NEW ZEALAND
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 1, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the file COPYING, which contains a copy of the GNU General
- Public License.
-
- Atari version ported by Graham Judd - gjudd@siward.demon.co.uk
-
- */
-
- /*---------------------------- Source Control ------------------------------*/
-
- /*
- * $Id: snews1.c,v 1.3 1994/02/05 19:34:56 gbj Exp user $
- */
-
-
- /****************************************************************************
- * 20 May 92 1.2 GT ka9q mods. *
- * 22 May 92 1.3 GT Set time zone. *
- * 05 Jun 92 1.4 GT Nikki Locke's SPACE command. *
- * 06 Jun 92 1.5 GT Invalidate freed pointers. *
- * 09 Jun 92 1.6 GT Right and left cursor keys. *
- * 12 Jun 92 1.7 NJL Add v_init call & change to use scr_lines. *
- * Add 'q' as alternative to ESC throughout. *
- * Fix memory leak when Escaping from read_thread. *
- * Ensure strtok() accepts tab as well as space. *
- * 17 Jul 92 1.8 GT C++ compilation. *
- * Heap debugging. *
- * Swap out when executing child process. *
- * 16 Aug 92 1.9 MSM Snews 1.9 *
- * Lock history etc. during use *
- * 31 May 93 1.10 MSM Snews 2.0 *
- * 18 Jun 93 1.11 MSM Heap debugging removed (using Bounds Check) *
- * 10 Jul 93 1.12 MSM New commands added, help updated *
- * 7 Aug 93 1.13 MSM Change command functionality to be TINish *
- * MSM Add expert mode *
- * MSM Add confirm exit mode *
- * 26 Aug 93 1.13 MSM Colour Support clean up, Expert toggle, bugs *
- * 3 Oct 92 1.14 MSM Case sensitive y/n questions made insensitive *
- * old style tab action added, new config options *
- * 132 col / 43 line support corrected *
- * article/thread save function corrected. *
- * 24 Nov 93 1.15 MSM Changed to Delta version control *
- * Session setting text changes *
- * 25 Nov 93 1.16 MSM Correct read list processing *
- * 5 Feb 94 AT2 GBJ Ported to Atari ST *
- * 2 Apr 94 1.17 MSM Add print thread support *
- * abort/replace/append choice for thread save *
- * 15.89 style added to smart match *
- * Save full newsgroup *
- * Suspend support *
- *****************************************************************************/
-
-
- #include <time.h>
- #include <io.h>
- #include <fcntl.h>
- #include "defs.h"
- #include "snews.h"
- #include "screen.h"
- #ifdef ATARI
- # include <sys/types.h>
- # include "st.h"
- # include "fileops.h"
- #else
- # include "exec.h"
- #endif
- #include "locking.h"
-
- #ifndef __TURBOC__
- #ifndef ATARI
- #include <graph.h>
- #include <dos.h>
- #define BLACK 0
- #define LIGHTGRAY 7
- unsigned long farcoreleft(void);
- #endif
- #endif
-
-
- int xfile = FALSE;
-
- INFO my_stuff;
- #ifdef ATARI
- unsigned long _STACK = 32768;
- #else
- unsigned _stklen = 16384;
- #endif
- char search_text[128];
- char save_name[65];
- char search_group[80];
-
- /*------------------------------- main --------------------------------*/
- void main(void)
- {
- ACTIVE *gp, *head;
- ACTIVE *tmp_ng;
- int articles, j, unread;
- int done;
-
- tzset();
- fprintf(stderr, "loading config... ");
- if (load_stuff()) {
-
- v_init(my_stuff.directvideo); /* initialise bios video package */
- if (mlock(my_stuff.news_dir, "history", "Snews") != 0) {
- printf("snews: Unable to lock history!\n");
- exit(2);
- }
- if (mlock(my_stuff.news_dir, my_stuff.user, "Snews") != 0) {
- printf("snews: Unable to lock user %s!\n", my_stuff.user);
- rmlock(my_stuff.news_dir, "history", "Snews");
- exit(2);
- }
- textbackground(textb);
- textcolor(textf);
- gotoxy(1, 1);
- clrscr();
- gotoxy((scr_cols/2) - 23, (scr_rows/2) - 8);
- printf("D E M O N I N T E R N E T S E R V I C E S");
- gotoxy((scr_cols/2) - 18, (scr_rows/2) - 6);
- printf("U s e n e t N e w s R e a d e r");
- gotoxy((scr_cols/2) - 11, (scr_rows/2) - 4);
- printf("Version %d.%02d [build %d]", rmj, rmm, rup);
- gotoxy((scr_cols/2) - 20, (scr_rows/2) - 2);
- printf("Based on Simple News 2.0 by John McCombs");
- #ifdef ATARI
- gotoxy((scr_cols/2) - 17, (scr_rows/2));
- textbackground(headb);
- textcolor(headf);
- printf("Support: gjudd@siward.demon.co.uk");
- textbackground(textb);
- textcolor(textf);
- #else
- gotoxy((scr_cols/2) - 14, (scr_rows/2));
- printf("Support: internet@demon.net");
- #endif
- gotoxy((scr_cols/2) - 1, (scr_rows/2) + 2);
- printf("or");
- gotoxy((scr_cols/2) - 26, (scr_rows/2) + 4);
- printf("Type 'B' at any menu and complete the questionnaire");
- gotoxy((scr_cols/2) - 31, (scr_rows/2) + 6);
- printf("Source available under GNU Licence by FTP from ftp.demon.co.uk");
-
- gotoxy(1, scr_rows - 1);
- printf("loading active... ");
- head = load_active_file();
- add_suspend(head);
- printf("loading read list... ");
- load_read_list();
- printf("loading history... ");
- load_history_list(1);
-
- done = FALSE;
- gp = NULL;
- strcpy(search_group, "demon.announce");
-
- while (!done) {
- if ((gp = select_group(head, gp)) != NULL) {
- if ((read_group(gp) == EX_NEXT) && (gp->next != NULL)) {
- tmp_ng = gp->next;
- unread = 0;
- while (tmp_ng != NULL) {
- articles = (int) (tmp_ng->hi_num - tmp_ng->lo_num);
- for (j=0;j<articles;j++) {
- if (*((tmp_ng->read_list) + j) == FALSE)
- unread++;
- }
- if (unread > 0)
- break;
- tmp_ng= tmp_ng->next;
- }
- if (unread > 0)
- gp = tmp_ng;
- else
- message("-- No more articles to read --");
- }
- }
- else
- done = TRUE;
- }
-
- textbackground(textb);
- textcolor(textf);
- clrscr();
-
- free_hist_list();
- save_read_list();
- close_active_file();
- rmlock(my_stuff.news_dir, "history", "Snews");
- rmlock(my_stuff.news_dir, my_stuff.user, "Snews");
- }
- else {
- fprintf(stderr, "Couldn't find neccessary item in the .rc files\n");
- }
- #ifdef ATARI
- printf("\033q\n");
- #endif
- }
-
- /*-------------------------- find which group to read ----------------------*/
- ACTIVE *select_group(ACTIVE * head, ACTIVE * current)
- {
-
- /*
- * Present the list of groups, and allow him to move up and down with
- * the arrow and PgUp and PgDn keys. 'h' for help
- */
-
- ACTIVE *top; /* newsgroup at the top of the page */
- ACTIVE *this_group; /* current newsgroup */
- ACTIVE *tmp_ng;
- int exit_code; /* why we are exiting the loop */
- char sub_tmp[80];
-
- int ch, i, j, articles, unread, ch2;
-
- this_group = (current == NULL) ? head : current;
-
- top = head;
- exit_code = 0;
-
- show_groups(&top, this_group, TRUE, head);
-
- while (exit_code == 0) {
-
- ch = getch();
- switch (ch) {
-
- case 0:
- case 0xE0:
- {
- ch = getch();
- switch (ch) {
-
- case Fn1:
- show_help(HELP_GROUP);
- show_groups(&top, this_group, TRUE, head);
- break;
-
- case Fn2:
- show_values();
- show_groups(&top, this_group, TRUE, head);
- break;
-
- case Fn3:
- change_values();
- show_groups(&top, this_group, TRUE, head);
- break;
-
- case UP_ARR:
- if (this_group->last != NULL)
- this_group = this_group->last;
- break;
-
- case DN_ARR:
- if (this_group->next != NULL)
- this_group = this_group->next;
- break;
-
- case PGUP:
- for (i = this_group->index - top->index;
- i < PAGE_LENGTH; i++) {
- if (this_group->last == NULL)
- break;
- this_group = this_group->last;
- }
- break;
-
- case PGDN:
- for (i = this_group->index - top->index;
- i < PAGE_LENGTH; i++) {
- if (this_group->next == NULL)
- break;
- this_group = this_group->next;
- }
- break;
-
- case HOME:
- top = this_group = head;
- show_groups(&top, this_group, TRUE, head);
- break;
-
- case END:
- top = this_group = head;
- while (this_group->next != NULL)
- this_group = this_group->next;
- break;
-
- case RT_ARR:
- exit_code = EX_DONE;
- break;
-
- } /* switch (ch) */
-
- break;
- }
-
- case '!':
- textbackground(headb);
- textcolor(headf);
- clrscr();
- #ifdef ATARI
- printf("Sorry, function not supported. \n\n");
- printf("Press a key to return to Snews.\n\n");
- getch();
- #else
- printf("Type <EXIT> to return to Snews.\n\n");
- system("");
- #endif
- textbackground(textb);
- textcolor(textf);
- clrscr();
- show_groups(&top, this_group, TRUE, head);
- break;
-
- case 'k':
- if (this_group->last != NULL)
- this_group = this_group->last;
- break;
-
- case 'j':
- if (this_group->next != NULL)
- this_group = this_group->next;
- break;
-
- case 2: /* ^B */
- case 21: /* ^U */
- case 'b':
- for (i = 0; i < PAGE_LENGTH; i++) {
- if (this_group->last == NULL)
- break;
- this_group = this_group->last;
- }
- break;
-
- case 4: /* ^D */
- case 6: /* ^F */
- case ' ':
- for (i = 0; i < PAGE_LENGTH; i++) {
- if (this_group->next == NULL)
- break;
- this_group = this_group->next;
- }
- break;
-
- case 'w':
- strcpy(sub_tmp, "");
- if (this_group->suspend == TRUE) {
- message("This group is suspende, post regardless ? (y/n ");
- ch2 = getch();
- ch2 = tolower(ch2);
- message("");
- }
- else
- ch2 = 'y';
- if (ch2 == 'y') {
- post(NULL, this_group->group, sub_tmp);
- show_groups(&top, this_group, TRUE, head);
- }
- break;
-
- case 'v':
- #ifdef ATARI
- sprintf(sub_tmp, "Demon Internet Simple News v%02d.%02d.%02d LC5 compiled %s", rmj, rmm, rup, __DATE__);
- #else
- #ifdef __TURBOC__
- sprintf(sub_tmp, "Demon Internet Simple News v%02d.%02d.%02d BC++ compiled %s", rmj, rmm, rup, __DATE__);
- #else
- sprintf(sub_tmp, "Demon Internet Simple News v%02d.%02d.%02d MSVC compiled %s", rmj, rmm, rup, __DATE__);
- #endif
- #endif
- message(sub_tmp);
- getch();
- show_groups(&top, this_group, TRUE, head);
- break;
-
- case 's':
- case 'S':
- save_group_to_disk(this_group);
- message("");
- break;
-
- case 'H':
- case 'h':
- show_help(HELP_GROUP);
- show_groups(&top, this_group, TRUE, head);
- break;
-
- case 'Z':
- case 'z':
- mark_group_as_unread(this_group);
- show_groups(&top, this_group, TRUE, head);
- break;
-
- case 'g':
- this_group = search_for_group(head, TRUE);
- break;
-
- case '/':
- case '+':
- case '=':
- this_group = search_for_group(this_group, TRUE);
- break;
-
- case '?':
- case '-':
- this_group = search_for_group(this_group, FALSE);
- break;
-
- case 'M':
- mail_to_someone(NULL);
- show_groups(&top, this_group, TRUE, head);
- break;
-
- case 'c':
- if (mark_group_as_read(this_group, TRUE) == TRUE)
- show_groups(&top, this_group, TRUE, head);
- else
- message("");
- break;
-
- case 'C':
- if (mark_group_as_read(this_group, TRUE) != TRUE) {
- message("");
- break;
- }
- show_groups(&top, this_group, TRUE, head);
- /* and drop into 'N' code */
-
- case 'N':
- tmp_ng = this_group;
- unread = 0;
- articles = (int) (tmp_ng->hi_num - tmp_ng->lo_num);
- for (j=0; j < articles; j++) {
- if (*((tmp_ng->read_list) + j) == FALSE)
- unread++;
- }
- if (unread > 0) {
- break;
- }
- else
- tmp_ng = this_group->next;
- unread = 0;
- while (tmp_ng != NULL) {
- articles = (int) (tmp_ng->hi_num - tmp_ng->lo_num);
- for (j = 0; j < articles; j++) {
- if (*((tmp_ng->read_list) + j) == FALSE)
- unread++;
- }
- if (unread > 0) {
- break;
- }
- tmp_ng = tmp_ng->next;
- }
- if (unread > 0) {
- this_group = tmp_ng;
- }
- else {
- message("-- No more unread articles --");
- }
- break;
-
- case TAB:
- case 'n':
- if (my_stuff.tab_action == TRUE) {
- tmp_ng = this_group;
- unread = 0;
- articles = (int) (tmp_ng->hi_num - tmp_ng->lo_num);
- for (j=0; j < articles; j++) {
- if (*((tmp_ng->read_list) + j) == FALSE)
- unread++;
- }
- if ((unread > 0) && (tmp_ng->suspend == FALSE)) {
- exit_code = EX_DONE;
- break;
- }
- else
- tmp_ng = this_group->next;
- unread = 0;
- while (tmp_ng != NULL) {
- articles = (int) (tmp_ng->hi_num - tmp_ng->lo_num);
- for (j = 0; j < articles; j++) {
- if (*((tmp_ng->read_list) + j) == FALSE)
- unread++;
- }
- if ((unread > 0) && (tmp_ng->suspend == FALSE)) {
- exit_code = EX_DONE;
- break;
- }
- unread = 0;
- tmp_ng = tmp_ng->next;
- }
- if ((unread > 0) && (tmp_ng->suspend == FALSE)) {
- this_group = tmp_ng;
- }
- else {
- message("-- No more articles to read --");
- }
- break;
- }
- else { /* old style action */
- tmp_ng = this_group->next;
- unread = 0;
- while (tmp_ng != NULL) {
- articles = (int) (tmp_ng->hi_num - tmp_ng->lo_num);
- for (j = 0; j < articles; j++) {
- if ( *((tmp_ng->read_list)+j) == FALSE)
- unread++;
- }
- if ((unread > 0) && (tmp_ng->suspend == FALSE))
- break;
- unread = 0;
- tmp_ng = tmp_ng->next;
- }
- if (unread > 0) {
- this_group = tmp_ng;
- } else {
- message("-- No more articles to read --");
- }
- break;
- }
-
- case ENTER:
- exit_code = EX_DONE;
- break;
-
- case ESCAPE:
- case 'Q':
- case 'q':
- if (my_stuff.exitconfirm != 1) {
- message(" EXIT - Are you sure (y/n) ? ");
- ch = getch();
- if (ch == 'y')
- exit_code = EX_QUIT;
- else
- show_groups(&top, this_group, TRUE, head);
- }
- else {
- exit_code = EX_QUIT;
- }
- break;
-
- case 'B':
- bug_report();
- show_groups(&top, this_group, TRUE, head);
- break;
-
- };
- if (exit_code == 0)
- show_groups(&top, this_group, FALSE, head);
- }
-
- if (exit_code == EX_DONE)
- return (this_group);
- else
- return (NULL);
-
- }
-
- /*----------------------- Search for a newsgroup --------------------------*/
- ACTIVE *search_for_group(ACTIVE *this_group, int direction)
- {
- char pattern[128];
- char prompt[80];
- ACTIVE *act;
- int found=FALSE;
- #ifdef ATARI
- ACTIVE *hit;
- /*
- This has been added because, as the routine stands, if the
- matched group is the very last in the list, then act == NULL
- and the assignment of act->last, act->next depending upon
- direction causes a bus error. So, hit is set to act which will
- not be NULL UNLESS the search string does not appear in ANY
- group name. If hit is NULL, this_group is returned.
- */
- #endif
-
- sprintf(prompt, "Search %s for [%s] ? ", direction ? "forwards" : "backwards",
- search_group);
- lmessage(prompt);
- gets(pattern);
- if (pattern[0] == 0x1b) {
- lmessage("");
- return this_group;
- }
-
- if (strlen(pattern) > 0) {
- strcpy(search_group, pattern);
- }
- else {
- strcpy(pattern, search_group);
- }
-
- message ("*** searching - please wait ***");
- hit = NULL;
- strlwr(pattern);
- if (direction) {
- for (act=this_group->next;!found && act!=NULL;act=act->next) {
- found = (strstr(act->group, pattern) != NULL);
- #ifdef ATARI
- if (found) {
- hit = act;
- break;
- }
- #endif
- }
- }
- else {
- for(act=this_group->last;!found && act!=NULL;act=act->last) {
- found = (strstr(act->group, pattern) != NULL);
- #ifdef ATARI
- if (found) {
- hit = act;
- break;
- }
- #endif
- }
- }
-
- lmessage("");
-
- #ifdef ATARI
- if (found && hit) {
- #else
- if (found) {
- #endif
- lmessage("");
- #ifdef ATARI
- return hit;
- #else
- return(direction ? act->last : act->next);
- #endif
- }
- else {
- sprintf(prompt, "*** %s not found - press any key ***", pattern);
- message(prompt);
- getch();
- message("");
- return this_group;
- }
- }
-
- /*---------------------------- help screen ---------------------------------*/
- void show_help(int h)
- {
-
- char *type[] = {"Newsgroup", "Thread", "Article"};
- char buf[256];
-
- textbackground(helpb);
- textcolor(helpf);
- clrscr();
- textbackground(headb);
- textcolor(headf);
- clreol();
- sprintf(buf, "%s Help (%s)\r\n", type[h], VERSION);
- gotoxy((scr_cols/2) - (strlen(buf)/2), 1);
- cprintf(buf);
- clreol();
- textbackground(helpb);
- textcolor(helpf);
-
- switch (h) {
- case HELP_GROUP:
-
- cprintf("\r\n\r\n");
- cprintf(" LIST NEWSGROUPS CHOOSING NEWSGROUPS\r\n\r\n");
- cprintf(" sUP move display up one page TAB go to next unread newsgroup\r\n");
- cprintf(" sDN move display down one page ENTER read selected newsgroup\r\n");
- cprintf(" Home move to top of list RIGHT read selected newsgroup\r\n");
- cprintf(" End move to bottom of list\r\n");
- cprintf(" UP move up one line\r\n");
- cprintf(" DOWN move down one line\r\n\r\n");
- cprintf(" POST ARTICLE SPECIAL ACTIONS\r\n\r\n");
- cprintf(" w post article in newsgroup c mark this newsgroup as read\r\n");
- cprintf(" C mark group as read and goto next\r\n");
- cprintf(" z mark this newsgroup as unread\r\n");
- cprintf(" F2 show user values\r\n");
- cprintf(" F3 Toggle Expert Mode\r\n");
- cprintf(" ESCAPE exit Snews\r\n");
- cprintf(" q exit Snews\r\n");
- cprintf(" v show version information\r\n");
-
- message("-- Press any key for next page --");
- getch();
-
- textbackground(helpb);
- textcolor(helpf);
- clrscr();
- textbackground(headb);
- textcolor(headf);
- clreol();
- sprintf(buf, "%s Help (%s)\r\n", type[h], VERSION);
- gotoxy((scr_cols/2) - (strlen(buf)/2), 1);
- cprintf(buf);
- clreol();
- textbackground(helpb);
- textcolor(helpf);
-
- cprintf("\r\n\r\n");
- cprintf(" MAIL\r\n\r\n");
- cprintf(" M mail to someone\r\n\r\n");
-
- cprintf(" SEARCHING\r\n\r\n");
-
- cprintf(" g search for newsgroup by name\r\n");
- cprintf(" + / search following for newsgroup\r\n");
- cprintf(" - ? search preceeding for newsgroups\r\n\r\n");
-
- cprintf(" MISCELLANEOUS\r\n\r\n");
- cprintf(" ! shell out (NOT SUPPORTED)\r\n");
- cprintf(" s save all articles in newsgroup to disk\r\n");
- cprintf(" B mail a support query to DEMON\r\n");
-
- break;
-
- case HELP_THREAD:
- cprintf("\r\n\r\n");
- cprintf(" LISTING THREADS READING THREADS\r\n\r\n");
-
- cprintf(" sUP move display up one page TAB read next unread article\r\n");
- cprintf(" sDN move display down one page BACKSP read the last/prev. article\r\n");
- cprintf(" Home move to top of list ENTER read the selected thread\r\n");
- cprintf(" End move to bottom of list RIGHT read the selected thread\r\n");
- cprintf(" UP move up one line LEFT display newsgroups\r\n");
- cprintf(" DOWN move down one line q display newsgroups\r\n\r\n");
-
- cprintf(" MARKING THREADS EXTRACT THREADS\r\n\r\n");
-
- cprintf(" c mark as read, go to groups s save thread to disk\r\n");
- cprintf(" C mark newsgroup as read S extract thread to mail \"%s\"\r\n", my_stuff.extruser);
- cprintf(" K mark current thread as read in mail directory\r\n");
- cprintf(" X mark all threads before\r\n");
- cprintf(" current as read\r\n");
- cprintf(" z mark current thread as unread\r\n");
-
- message("-- Press any key for next page --");
- getch();
-
- textbackground(helpb);
- textcolor(helpf);
- clrscr();
- textbackground(headb);
- textcolor(headf);
- clreol();
- sprintf(buf, "%s Help (%s)\r\n", type[h], VERSION);
- gotoxy((scr_cols/2) - (strlen(buf)/2), 1);
- cprintf(buf);
- clreol();
- textbackground(helpb);
- textcolor(helpf);
-
- cprintf("\r\n\r\n");
- cprintf(" MAIL POSTING\r\n\r\n");
-
- cprintf(" M mail to someone w post article to newsgroup\r\n\r\n");
-
- cprintf(" SEARCHING\r\n\r\n");
- cprintf(" + search for text in following subjects\r\n");
- cprintf(" / search for text in following bodies\r\n");
- cprintf(" - search for text in preceeding subjects\r\n");
- cprintf(" ? search for text in preceeding bodies\r\n\r\n");
-
- cprintf(" MISCELLANEOUS\r\n\r\n");
-
- cprintf(" F2 show user values v show version information\r\n");
- cprintf(" F3 Toggle Expert Mode\r\n");
- cprintf(" ! shell out (NOT SUPPORTED)\r\n");
- cprintf(" B mail a support query to DEMON\r\n");
-
- break;
-
- case HELP_ARTICLES:
-
- cprintf("\r\n\r\n");
- cprintf(" READING ARTICLES CHOOSING ARTICLES\r\n\r\n");
-
- cprintf(" sUP move display up one page TAB read next page / unread article\r\n");
- cprintf(" sDN move display down one page ENTER read next article\r\n");
- cprintf(" Home move to top of article RIGHT read next article in thread\r\n");
- cprintf(" End move to bottom of article LEFT read prior article in thread\r\n");
- cprintf(" UP move up one line p read prior article in thread\r\n");
- cprintf(" DOWN move down one line < read first article in thread\r\n");
- cprintf(" b move back one page > read last article in thread\r\n");
- cprintf(" n mark this article as read\r\n");
- cprintf(" and read next unread MISCELLANEOUS\r\n");
- cprintf(" K mark this and remainder of\r\n");
- cprintf(" thread as read ! shell out (NOT SUPPORTED)\r\n");
- cprintf(" z mark this article unread\r\n");
- cprintf(" d ROT13 this article\r\n");
-
- message("-- Press any key for next page --");
- getch();
-
- textbackground(helpb);
- textcolor(helpf);
- clrscr();
- textbackground(headb);
- textcolor(headf);
- clreol();
- sprintf(buf, "%s Help (%s)\r\n", type[h], VERSION);
- gotoxy((scr_cols/2) - (strlen(buf)/2), 1);
- cprintf(buf);
- clreol();
- textbackground(helpb);
- textcolor(helpf);
-
- cprintf("\r\n\r\n");
- cprintf(" POST ARTICLE SEND MAIL\r\n\r\n");
-
- cprintf(" w post new article r mail reply to author\r\n");
- cprintf(" f post follow-up article R mail reply to someone\r\n");
- cprintf(" m mail article to someone\r\n");
- cprintf(" M mail to someone\r\n\r\n");
-
- cprintf(" SPECIAL ACTION EXTRACT ARTICLES\r\n\r\n");
-
- cprintf(" d decode ROT-13 article s save article to file\r\n");
- cprintf(" F2 show user values S extract article to mail \"%s\"\r\n", my_stuff.extruser);
- cprintf(" F3 Toggle Expert Mode in mail directory\r\n");
- cprintf(" B Mail a support query o print article\n\r");
- cprintf(" v show version information\r\n\r\n");
-
- cprintf(" SEARCHING\r\n\r\n");
-
- cprintf(" + / search for text in following articles\r\n");
- cprintf(" - ? search for text in preceding articles\r\n");
-
- break;
- };
-
- message("-- Press any key to continue --");
- getch();
-
- }
-
-
- /*-------------- show the values of user defined variables -------------*/
- void show_values(void)
- {
- char buf[256];
-
- textbackground(helpb);
- textcolor(helpf);
- clrscr();
- textbackground(headb);
- textcolor(headf);
- #ifdef ATARI
- printf("%*s", scr_cols, " ");
- #else
- clreol();
- #endif
- sprintf(buf, "Pre-set User values (%s)\r\n", VERSION);
- gotoxy((scr_cols/2) - (strlen(buf)/2), 1);
- cprintf(buf);
- #ifndef ATARI
- clreol();
- #endif
- textbackground(helpb);
- textcolor(helpf);
- #ifndef ATARI
- cprintf("\r\n\r\n");
- #endif
- gotoxy(1, 4);
-
- cprintf(" User Name: %s@%s.%s (%s)\r\n\r\n", my_stuff.user, my_stuff.my_site,
- my_stuff.my_domain, my_stuff.my_name);
-
- cprintf(" Local node name: %s\r\n", my_stuff.my_site);
- cprintf(" Mail Server: %s\r\n", my_stuff.mail_server);
- cprintf(" Organization: %s\r\n\r\n", my_stuff.my_organisation);
-
- cprintf(" Signature File: %s%s\r\n", my_stuff.home, my_stuff.signature);
- cprintf(" Reply To: %s\r\n\r\n", my_stuff.replyuser);
- cprintf(" File Editor: %s\r\n", my_stuff.editor);
- cprintf(" Edit Parameters: %s\r\n\r\n", my_stuff.edit_line);
-
- cprintf(" News Home Directory: %s\r\n", my_stuff.news_dir);
- cprintf(" Mail Directory: %s\r\n", my_stuff.mail_dir);
- cprintf(" Spool Directory: %s\r\n\r\n", my_stuff.spooldir);
-
- cprintf(" Posts saved to user: %s\r\n", my_stuff.mailuser);
- cprintf(" Mail saved to user: %s\r\n", my_stuff.maillog);
- cprintf(" Extracts saved to user: %s\r\n\r\n", my_stuff.extruser);
-
- message("-- Press any key for next page --");
- getch();
-
- textbackground(helpb);
- textcolor(helpf);
- clrscr();
- textbackground(headb);
- textcolor(headf);
- #ifdef ATARI
- printf("%*s", scr_cols, " ");
- #else
- clreol();
- #endif
- sprintf(buf, "Pre-set User values (%s)\r\n", VERSION);
- gotoxy((scr_cols/2) - (strlen(buf)/2), 1);
- cprintf(buf);
- #ifndef ATARI
- clreol();
- #endif
- textbackground(helpb);
- textcolor(helpf);
- #ifndef ATARI
- cprintf("\r\n\r\n");
- #endif
- gotoxy(1, 4);
-
- cprintf(" Quoting string: \"%s\"\r\n", my_stuff.quotemark);
- cprintf(" News articles mailed to: %s@%s\r\n\r\n", my_stuff.mail_id, my_stuff.mail_server);
-
- cprintf(" Temporary file location: %s\r\n", my_stuff.temp_name);
- cprintf(" Incoming news directory: %s\r\n", my_stuff.incoming_dir);
- cprintf(" Mail home directory: %s\r\n", my_stuff.home);
- cprintf(" ka9q nntp directory: %s\r\n", my_stuff.nntp_dir);
- cprintf(" Alias name file: %s\r\n\r\n", my_stuff.alias_file);
-
- cprintf(" Local posting enabled: %s\r\n", my_stuff.localpost ? "Yes" : "No");
- cprintf(" Mark local post as read: %s\r\n\r\n", my_stuff.localread ? "Yes" : "No");
- cprintf(" Prompt before exit: %s\r\n", my_stuff.exitconfirm ? "No" : "Yes");
- cprintf(" Expert mode: %s\r\n", my_stuff.expert ? "Yes" : "No");
- cprintf(" TAB Style: %s\r\n", my_stuff.tab_action ? "New" : "Old");
- cprintf(" Quote Headers: %s\r\n", my_stuff.header_quote ? "Quoted" : "Not Quoted");
- cprintf(" Quote Footers: %s\r\n", my_stuff.footer_quote ? "Quoted" : "Not Quoted");
- // cprintf(" New Threads Only: %s\r\n", my_stuff.show_unread ? "No" : "Yes");
- cprintf(" Subject Match Length: %d characters\r\n", my_stuff.match_len);
-
- message("-- Press any key to continue --");
- getch();
-
- }
-
- /*------------- Change selected config values for the session -------------*/
- void change_values()
- {
-
- int ch;
- char buf[256];
-
- textbackground(helpb);
- textcolor(helpf);
- clrscr();
- textbackground(headb);
- textcolor(headf);
- #ifdef ATARI
- printf("%*s", scr_cols, " ");
- #else
- clreol();
- #endif
- sprintf(buf, "Settings for this session (%s)\r\n", VERSION);
- gotoxy((scr_cols/2) - (strlen(buf)/2), 1);
- cprintf(buf);
- #ifndef ATARI
- clreol();
- #endif
- textbackground(helpb);
- textcolor(helpf);
- #ifndef ATARI
- cprintf("\r\n\r\n");
- #endif
-
- do
- {
- gotoxy(5, 6);
- cprintf("(E)xpert mode: %s", my_stuff.expert ? "On " : "Off");
- gotoxy(5, 8);
- cprintf("(T)ab mode: %s", my_stuff.tab_action ? "New" : "Old");
- gotoxy(5, 10);
- cprintf("(H)eader Quoting: %s", my_stuff.header_quote ? "On " : "Off");
- gotoxy(5, 12);
- cprintf("(F)ooter Quoting: %s", my_stuff.footer_quote ? "On " : "Off");
- // gotoxy(5, 14);
- // cprintf("(S)how Read: %s", my_stuff.show_unread ? "Off" : "On ");
- message("Enter value to toggle, ESC to exit (E/T/H/F) ");
- textbackground(helpb);
- textcolor(helpf);
- ch = getch();
- ch = tolower(ch);
- if (ch == 'q')
- ch = ESCAPE;
- switch (ch) {
- case 'e':
- if (my_stuff.expert == TRUE)
- my_stuff.expert = FALSE;
- else
- my_stuff.expert = TRUE;
- break;
- case 't':
- if (my_stuff.tab_action == TRUE)
- my_stuff.tab_action = FALSE;
- else
- my_stuff.tab_action = TRUE;
- break;
- case 'h':
- if (my_stuff.header_quote == TRUE)
- my_stuff.header_quote = FALSE;
- else
- my_stuff.header_quote = TRUE;
- break;
- case 'f':
- if (my_stuff.footer_quote == TRUE)
- my_stuff.footer_quote = FALSE;
- else
- my_stuff.footer_quote = TRUE;
- break;
- // case 's':
- // if (my_stuff.show_unread == TRUE)
- // my_stuff.show_unread = FALSE;
- // else
- // my_stuff.show_unread = TRUE;
- // break;
- }
- }
- while (ch != ESCAPE);
- lmessage("");
- }
-
- /*-------------------- show the list of active groups -----------------------*/
- void show_groups(ACTIVE ** top, ACTIVE * this_group, int force, ACTIVE *head)
- {
-
- /*
- * This routine takes 'top', a pointer to the first line on the screen
- * and 'this_group' a pointer to where we want to be, and updates the
- * screen. A marker to this_group is maintained, and the screen is
- * repainted, where necessary
- */
-
- static last_y;
- static last_index;
- int i, ur;
- ACTIVE *that;
- char buf[80], lbrack, rbrack;
-
- /*
- * If 'this_group' is above the 'top' or it is more than a screen
- * length below, or 'this_group and 'top' are both zero, ie first
- * time repaint the screen
- */
-
- if (force ||
- ((*top)->index > this_group->index) ||
- (this_group->index - (*top)->index) > PAGE_LENGTH - 1) {
-
- clrscr();
- textbackground(headb);
- textcolor(headf);
- #ifdef ATARI
- for (i=0; i < 2; i++)
- printf("%*s", scr_cols, " ");
- #else
- clreol();
- #endif
- gotoxy((scr_cols/2) - 8, 1);
- cprintf("Select Newsgroup\r\n");
- #ifndef ATARI
- clreol();
- #endif
- gotoxy(scr_cols - 20, 2);
- cprintf("Group %3d of %3d\r\n", last_index+1, head->groups);
- #ifndef ATARI
- clreol();
- #endif
- textbackground(textb);
- textcolor(textf);
-
- /* now adjust the top */
- *top = this_group;
- for (i = 0; i < PAGE_LENGTH / 2; i++) {
- if ((*top)->last == NULL)
- break;
- *top = (*top)->last;
- }
-
- that = *top;
- for (i = 0; i < PAGE_LENGTH; i++) {
- ur = count_unread_in_group(that);
- gotoxy(8, i+5);
- if (that->suspend == TRUE) {
- lbrack = '[';
- rbrack = ']';
- }
- else
- lbrack = rbrack = ' ';
- if (ur > 0) {
- printf("%4d %4ld %c%s%c ", ur, that->hi_num - that->lo_num,
- lbrack, that->group, rbrack);
- }
- else
- printf(" %4ld %c%s%c", that->hi_num - that->lo_num,
- lbrack, that->group, rbrack);
- that = that->next;
- if (that == NULL)
- break;
- }
-
- last_y = this_group->index - (*top)->index;
- gotoxy(4, last_y + PAGE_HEADER+1);
- putch('-'); putch('>');
- last_index = this_group->index;
-
- }
- else {
-
- gotoxy(4, last_y + PAGE_HEADER+1);
- putch(' '); putch(' '); /* deliberate putch for HBJ */
-
- last_y += (this_group->index - last_index);
- gotoxy(4, last_y + PAGE_HEADER+1);
- putch('-'); putch('>');
- last_index = this_group->index;
-
- }
- gotoxy(scr_cols - 20,2);
- textbackground(headb); textcolor(headf);
- cprintf("Group %3d of %3d\r\n", last_index+1, head->groups);
- textbackground(textb); textcolor(textf);
-
- sprintf(buf, "ESC=quit TAB=next unread group ENTER=read group F1 or 'h'=help [%ldk]",
- farcoreleft() / 1024);
- command(buf);
- }
-
-
-
-
- /*--------------------------- process message -------------------------------*/
- int read_group(ACTIVE * gp)
- {
-
- /*
- * We now have newsgroup. Access the directory and try to read
- * the newsgroup articles, extracting the headers.
- */
-
- ARTICLE *start;
- int exit_code;
- #ifdef ATARI
- // int i;
- #endif
-
- if (gp->lo_num < gp->hi_num) {
-
- clrscr();
- textbackground(headb);
- textcolor(headf);
- #ifdef ATARI
- // for (i=0; i < 3; i++)
- // printf("%*s", scr_cols, " ");
- #else
- clreol();
- gotoxy((scr_cols/2) - 7, 1);
- printf("Select Thread\n");
- clreol();
- printf("Group: %s ", gp->group);
- clreol();
- #endif
- textbackground(textb);
- textcolor(textf);
-
- start = get_headers(gp);
-
- exit_code = select_thread(gp, start);
-
- free_header(start);
- start = NULL;
- }
- return (exit_code);
- }
-
-
- /*------------------------- show the list of threads -----------------------*/
- void show_threads(ACTIVE * gp, ARTICLE ** top, ARTICLE * this_group,
- int force, ARTICLE *head)
- {
-
- /*
- * This routine takes 'top', a pointer to the first line on the screen
- * and 'this_group' a pointer to where we want to be, and updates the
- * screen. A maker to this_group is maintained, and the screen is
- * repainted, where necessary
- */
-
- static last_y;
- static last_index;
- int i;
- ARTICLE *that;
- int unread;
- int ur;
- char buf[80];
-
- /*
- * If 'this_group' is above the 'top' or it is more than a screen
- * length below, or'this_group and 'top' are both zero, ie first
- * time repaint the screen
- */
-
- if (force ||
- ((*top)->index > this_group->index) ||
- (this_group->index - (*top)->index) > PAGE_LENGTH - 1) {
-
- for(that=head, ur=0;that;that=that->next)
- ur += count_unread_in_thread(gp, that);
-
- clrscr();
- textbackground(headb);
- textcolor(headf);
- #ifdef ATARI
- for (i=0; i < 3; i++)
- printf("%*s", scr_cols, " ");
- #else
- clreol();
- #endif
- gotoxy((scr_cols/2) - 7, 1);
- cprintf("Select Thread\r\n");
- #ifndef ATARI
- clreol();
- #endif
- cprintf("Group: %s", gp->group);
- gotoxy(scr_cols - 25, 2);
- cprintf("%4ld Articles, %4d unread\r\n", gp->hi_num - gp->lo_num, ur);
- #ifndef ATARI
- clreol();
- #endif
- gotoxy(scr_cols - 25, 3);
- cprintf("Thread %4d of %4d", last_index+1, gp->threads);
- textbackground(textb);
- textcolor(textf);
-
- /* now adjust the top */
- *top = this_group;
- for (i = 0; i < PAGE_LENGTH / 2; i++) {
- if ((*top)->last == NULL)
- break;
- *top = (*top)->last;
- }
-
- that = *top;
- for (i = 0; i < PAGE_LENGTH; i++) {
- unread = count_unread_in_thread(gp, that);
- gotoxy(8, i + 5);
- if (unread > 0)
- printf("%4d %4d %s", unread, that->num_articles, that->header);
- else
- printf(" %4d %s", that->num_articles, that->header);
- that = that->next;
- if (that == NULL)
- break;
- }
-
- last_y = this_group->index - (*top)->index;
- gotoxy(4, last_y + PAGE_HEADER+1);
- putch('-'); putch('>');
- last_index = this_group->index;
- }
- else {
-
- gotoxy(4, last_y + PAGE_HEADER+1);
- putch(' '); putch(' '); /* deliberate for HBJ */
- last_y += (this_group->index - last_index);
- gotoxy(4, last_y + PAGE_HEADER+1);
- putch('-'); putch('>');
- last_index = this_group->index;
-
- }
- gotoxy(scr_cols - 25, 3);
- textbackground(headb); textcolor(headf);
- cprintf("Thread %4d of %4d", last_index+1, gp->threads);
- textbackground(textb); textcolor(textf);
-
- sprintf(buf, "ESC=select group TAB=next unread ENTER=next article F1 or 'h'=help [%ldk]",
- farcoreleft() / 1024);
- command(buf);
- }
-
- /*-------------------------- search through threads ------------------------*/
- ARTICLE *search_thread(ACTIVE *gp, ARTICLE *head, int search_body, int direction)
- {
- int found = 0, irq = FALSE;
- ARTICLE *this_art;
- ART_ID *art;
- TEXT *tx;
- LINES *text;
- char *fn;
- char prompt[128], pattern[128];
-
- if (head == NULL)
- return head;
-
- sprintf(prompt, "Search %s %s for ? [%s] ",
- search_body ? "articles" : "subjects",
- direction ? "forwards" : "backwards", search_text);
- lmessage(prompt);
- gets(pattern);
- if (pattern[0] == 0x1b)
- return 0;
-
- if (strlen(pattern) > 0)
- strcpy(search_text, pattern);
- else
- strcpy(pattern, search_text);
-
- strlwr(pattern);
- if (search_body) {
- message("** searching - please wait (press <ESC> to abort) ***");
-
- if (direction) {
- for (this_art=head; this_art!=NULL; this_art=this_art->next) {
-
- /* for each article */
- for (art=this_art->art_num; art!=NULL; art=art->next_art) {
- fn = make_news_group_name(gp->group);
- tx = load_article(fn, art->art_off, FALSE);
-
- for (text=tx->start; !found && text!=NULL; text=text->next) {
- strlwr(text->data);
- found = (strstr(text->data, pattern) != NULL);
- }
-
- free_article(tx);
-
- if (kbhit())
- irq = (getch() == 27);
-
- if (found || irq)
- break;
- }
-
- if (found || irq)
- break;
- }
- }
- else {
- for (this_art=head->last; this_art!=NULL; this_art=this_art->last) {
-
- /* for each article */
- for (art=this_art->art_num; art!=NULL; art=art->next_art) {
- fn = make_news_group_name(gp->group);
- tx = load_article(fn, art->art_off, FALSE);
-
- for (text=tx->start; !found && text!=NULL; text=text->next) {
- strlwr(text->data);
- found = (strstr(text->data, pattern) != NULL);
- }
-
- free_article(tx);
-
- if (kbhit())
- irq = (getch() == 27);
-
- if (found || irq)
- break;
- }
-
- if (found || irq)
- break;
- }
- }
- }
- else {
-
- if (direction) {
- for (this_art=head; this_art!=NULL; this_art=this_art->next) {
- strcpy(prompt, this_art->header);
- strlwr(prompt);
- found = (strstr(prompt, pattern) != NULL);
-
- if (found)
- break;
- }
- }
- else {
- for (this_art=head->last; this_art!=NULL; this_art=this_art->last) {
- strcpy(prompt, this_art->header);
- strlwr(prompt);
- found = (strstr(prompt, pattern) != NULL);
-
- if (found)
- break;
- }
- }
- }
- if (!found && !irq) {
- sprintf(prompt, "*** '%s' not found - press any key ***", pattern);
- message(prompt);
- getch();
- }
- return found ? this_art : head;
- }
-